/**
 * 
 * @author  phoenics@126.com
 * @version v.0.1
 * @date  2018年3月14日 下午2:09:13 
 * 
 */
package phoenics.upservice.servlet;

import java.io.IOException;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.Optional;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import phoenics.upservice.auth.JwtAuthentication;
import phoenics.upservice.entity.User;
import phoenics.upservice.service.JwtService;

/**
 *
 */
@Component
public class JwtTokenFilter implements Filter {  
	private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(JwtTokenFilter.class);
	private JwtService jwtService;  
	private final static String NEWTOKEN="reset";
    public JwtTokenFilter(@Autowired JwtService jwtService){  
        this.jwtService = jwtService;  
    }  
  
    @Override  
    public void init(FilterConfig filterConfig) throws ServletException {  
    }  
  
    @Override  
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {  
        HttpServletRequest servletRequest = (HttpServletRequest) request;
        HttpServletResponse servletResponse = (HttpServletResponse) response;
        String authorization = servletRequest.getHeader("Authorization");  
        if (authorization != null && authorization.startsWith("Bearer ")) {
            Optional<JwtAuthentication> jwtAuth=Optional.empty();
            try{
                jwtAuth =jwtService.parse(authorization.replaceAll("Bearer ", ""))  ;
                String token =jwtAuth.map(this::changeToken).orElse(NEWTOKEN);
                servletResponse.setHeader("newtoken",token);
            }catch (ExpiredJwtException e){
                servletResponse.setHeader("newtoken",NEWTOKEN);
            }

            //Optional<JwtAuthentication> jwtAuth =jwtService.parse(authorization.replaceAll("Bearer ", ""))  ;
            jwtAuth.ifPresent(jwtAuthentication -> SecurityContextHolder
                .getContext()
                .setAuthentication(jwtAuthentication)); 
        }  
        chain.doFilter(request, response);  
    }  
  
    @Override  
    public void destroy() {  
    }
    private boolean isExpired(Claims claims){
        long date=claims.getExpiration().getTime();
        long newDate=date-System.currentTimeMillis()-(1000L*3600L*24L*6L);
        return newDate<=0;

    }
    private String changeToken (JwtAuthentication j){
        if(isExpired((Claims)j.getDetails())){
            return jwtService.generate((User)j.getPrincipal());
        }
        return (String)j.getCredentials();
    }
}
